package com.simple.database.service;

import java.util.Collection;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

import com.simple.database.pojo.Function;

/**
 * 
 * @项目名称：wupao-common
 * @类名称：RedisService
 * @类描述：Redis操作工具类
 * @author fw
 * @创建时间：2015年10月13日 下午3:01:38 
 * @version：1.0.0
 */
@Service
public class RedisService {

	// 设置required=false，如果Spring容器中有就注入，没有忽略
	@Autowired(required = false)
	private ShardedJedisPool shardedJedisPool;
	
	

	/**
	 * 
	 * @描述：执行方法
	 * @创建时间：2015年10月13日 下午3:39:58
	 * @param fun
	 * @return
	 */
	private <T> T execute(Function<ShardedJedis, T> fun) {
		ShardedJedis shardedJedis = null;
		try {
			// 从连接池中获取到jedis分片对象
			shardedJedis = shardedJedisPool.getResource();
			return fun.callback(shardedJedis);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != shardedJedis) {
				// 关闭，检测连接是否有效，有效则放回到连接池中，无效则重置状态
				shardedJedis.close();
			}
		}
		return null;
	}

	/**
	 * 
	 * @描述：执行SET操作
	 * @创建时间：2015年10月13日 下午3:40:38
	 * @param key 键
	 * @param value 值
	 * @return
	 */
	public String set(final String key, final String value) {
		return this.execute(new Function<ShardedJedis, String>() {
			
			public String callback(ShardedJedis jedis) {
				return jedis.set(key, value);
			}
		});
	}

	/**
	 * 
	 * @描述：执行GET操作
	 * @创建时间：2015年10月13日 下午3:41:00
	 * @return
	 */
	public Collection<Jedis> getAll() {
		return this.execute(new Function<ShardedJedis, Collection<Jedis>>() {
			
			public Collection<Jedis> callback(ShardedJedis jedis) {
				return jedis.getAllShards();
			}
		});
	}

	/**
	 * 
	 * @描述：执行SET操作，并且指定生存时间
	 * @创建时间：2015年10月13日 下午3:41:57
	 * @param key 键
	 * @param value 值
	 * @param seconds 生存时间，单位为秒
	 * @return
	 */
	public String set(final String key, final String value,
			final Integer seconds) {
		return this.execute(new Function<ShardedJedis, String>() {
			
			public String callback(ShardedJedis jedis) {
				String str = jedis.set(key, value);
				// 设置生存时间
				jedis.expire(key, seconds);
				return str;
			}
		});
	}

	/**
	 * 
	 * @描述：设置生存时间
	 * @创建时间：2015年10月13日 下午3:42:26
	 * @param key 键
	 * @param seconds 时间，单位秒
	 * @return
	 */
	public Long expire(final String key, final Integer seconds) {
		return this.execute(new Function<ShardedJedis, Long>() {
			
			public Long callback(ShardedJedis jedis) {
				// 设置生存时间
				return jedis.expire(key, seconds);
			}
		});
	}

	/**
	 * 
	 * @描述：执行GET操作
	 * @创建时间：2015年10月13日 下午3:42:54
	 * @param key 获取值对应的键
	 * @return
	 */
	public String get(final String key) {
		return this.execute(new Function<ShardedJedis, String>() {
			
			public String callback(ShardedJedis jedis) {
				return jedis.get(key);
			}
		});
	}

	/**
	 * 
	 * @描述：根据键删除一个键值对
	 * @创建时间：2015年10月13日 下午3:43:15
	 * @param key 键
	 * @return
	 */
	public Long del(final String key) {
		return this.execute(new Function<ShardedJedis, Long>() {
			
			public Long callback(ShardedJedis jedis) {
				return jedis.del(key);
			}
		});
	}

	/**
	 * 
	 * @描述：添加hash结构数据
	 * @创建时间：2015年10月13日 下午3:43:49
	 * @param key 外层键
	 * @param itemId 内层键
	 * @param value 内层值
	 * @return
	 */
	public Long hset(final String key, final Long itemId, final String value) {
		return this.execute(new Function<ShardedJedis, Long>() {

			public Long callback(ShardedJedis jedis) {
				return jedis.hset(key, itemId + "", value);
			}
		});
	}

	/**
	 * 
	 * @描述：添加hash结构数据，并设置生存时间
	 * @创建时间：2015年10月13日 下午3:44:51
	 * @param key 键
	 * @param innerKey 内层键
	 * @param value 内层值
	 * @param seconds 生存时间，单位秒
	 * @return
	 */
	public Long hset(final String key, final String innerKey,
			final String value, final Integer seconds) {
		return this.execute(new Function<ShardedJedis, Long>() {

			
			public Long callback(ShardedJedis jedis) {
				Long count = jedis.hset(key, innerKey, value);
				// jedis.expire(key, seconds);
				return count;
			}
		});
	}

	/**
	 * 
	 * @描述：获取hash结构数据
	 * @创建时间：2015年10月13日 下午3:45:50
	 * @param key 键
	 * @param innerKey 内层键
	 * @return
	 */
	public String hget(final String key, final Long innerKey) {
		return this.execute(new Function<ShardedJedis, String>() {

			
			public String callback(ShardedJedis jedis) {
				return jedis.hget(key, innerKey + "");
			}
		});
	}

	/**
	 * 
	 * @描述： 获取hash结构的值
	 * @创建时间：2015年10月13日 下午3:46:56
	 * @param outerKey 外层键
	 * @param innerKey 内层键
	 * @return 
	 */
	public String hget(final String outerKey, final String innerKey) {
		return this.execute(new Function<ShardedJedis, String>() {

			
			public String callback(ShardedJedis jedis) {
				return jedis.hget(outerKey, innerKey);
			}
		});
	}

	/**
	 * 
	 * @描述：删除hash结构中的数据
	 * @创建时间：2015年10月13日 下午3:47:46
	 * @param key 键
	 * @param innerKeys 内层键 
	 * @return
	 */
	public Long hdel(final String key, final String... innerKeys) {
		return this.execute(new Function<ShardedJedis, Long>() {

			
			public Long callback(ShardedJedis jedis) {
				return jedis.hdel(key, innerKeys);
			}
		});

	}

	/**
	 * 
	 * @描述：查询所有
	 * @创建时间：2015年10月13日 下午3:48:15
	 * @param key 键
	 * @return
	 */
	public Map<String, String> hgetAll(final String key) {
		return this.execute(new Function<ShardedJedis, Map<String, String>>() {

			
			public Map<String, String> callback(ShardedJedis jedis) {
				return jedis.hgetAll(key);
			}
		});

	}

	/**
	 * 
	 * @描述：添加hash结构数据
	 * @创建时间：2015年10月13日 下午3:48:38
	 * @param ticket 键
	 * @param key 内层键
	 * @param jsonUser 值
	 * @return
	 */
	public Long hset(final String ticket, final String key,
			final String jsonUser) {
		return this.execute(new Function<ShardedJedis, Long>() {

			
			public Long callback(ShardedJedis jedis) {
				return jedis.hset(ticket, key, jsonUser);
			}

		});
	}
	
	/**
	 * 
	 * @描述：获取ShardedJedis对象
	 * @创建人：方伟
	 * @创建时间：2016年5月5日 上午10:57:36
	 * @return
	 */
	public ShardedJedis getShardedJedisPool(){
		return shardedJedisPool.getResource();
	}
	/**
	 * 
	 * @描述：出现异常时,释放资源，否则会出现缓冲区可能还存在数据，导致循环异常
	 * @创建人：张亚军
	 * @创建时间：2016年5月6日 下午1:36:58
	 * @param shardedJedis
	 */
	public void cleanJedis(ShardedJedis shardedJedis){
		if(shardedJedis!=null){
			shardedJedisPool.returnBrokenResource(shardedJedis);

		}
	}
	public void returnResource(ShardedJedis shardedJedis){
		if(shardedJedis!=null){
			shardedJedisPool.returnResource(shardedJedis);

		}
	}
}
